﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Microformats.Controls;
using System.ComponentModel;
using System.Web.UI;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Web;
using System.Web.UI.WebControls;
using Microformats.Enums;
using System.Globalization;

namespace Microformats.Controls
{
    public class Address : Entity
    {
        public Address()
        {
            ClassName = "adr";
        }

        /// <summary>
        /// Gets or sets the type.
        /// </summary>
        /// <value>The type.</value>
        [Browsable(true)]
        [Category("Address properties")]
        [Description("Specifies the address type.")]
        public AddressTypes Type { get; set; }

        /// <summary>
        /// Gets or sets the type.
        /// </summary>
        /// <value>The type.</value>
        [Browsable(true)]
        [Category("Address properties")]
        [Description("Specifies the address is a label.")]
        public bool Label { get; set; }

        /// <summary>
        /// Gets or sets the name of the country.
        /// </summary>
        /// <value>The name of the country.</value>
        [Browsable(true)]
        [Category("Address Parameter")]
        [Description("Specifies to use the state code")]
        public bool StateCode { get; set; }

        /// <summary>
        /// Gets or sets the name of the country.
        /// </summary>
        /// <value>The name of the country.</value>
        [Browsable(true)]
        [Category("Address Parameter")]
        [Description("Specifies to use the country code")]
        public bool CountryCode { get; set; }


        [Browsable(true)]
        [Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
        [Category("Address properties")]
        [Description("Address properties")]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public Collection<AddressContainer> AddressContainerCollection
        {
            get;
            set;
        }

        public void Render(ref HtmlTextWriter writer)
        {
            writer.WriteLine();

            string className = this.ClassName;

            if (this.Label)
            {
                className = string.Format("{0) label", className);
            }

            writer.AddAttribute(HtmlTextWriterAttribute.Class, className);
            writer.RenderBeginTag(this.HtmlTag);

            if (this.Type != AddressTypes.None)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Class, "type");
                writer.RenderBeginTag(HtmlTextWriterTag.Div);

                switch (this.Type)
                {
                    case AddressTypes.Work:
                        writer.Write("work");
                        break;
                    case AddressTypes.Home:
                        writer.Write("home");
                        break;
                    case AddressTypes.Preferred:
                        writer.Write("pref");
                        break;
                    case AddressTypes.Postal:
                        writer.Write("postal");
                        break;
                    case AddressTypes.Parcel:
                        writer.Write("parcel");
                        break;
                    case AddressTypes.Domestic:
                        writer.Write("dom");
                        break;
                    case AddressTypes.International:
                        writer.Write("intl");
                        break;
                    default:
                        break;
                }

                writer.RenderEndTag();
            }

            foreach (AddressContainer addressContainer in this.AddressContainerCollection)
            {
                if (addressContainer.HtmlTag != HtmlTextWriterTag.Unknown)
                {
                    HtmlTextWriterTag tag = addressContainer.HtmlTag;
                    writer.RenderBeginTag(addressContainer.HtmlTag);
                }

                foreach (AddressProperty addressProperty in addressContainer.AddressPropertyCollection)
                {
                    HtmlTextWriterTag tag = addressProperty.HtmlTag;
                    string value = addressProperty.Value;

                    switch (addressProperty.Type)
                    {
                        case AddressElement.PostOfficeBox:
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "post-office-box");
                            break;
                        case AddressElement.StreetAddress:
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "street-address");
                            break;
                        case AddressElement.ExtendedAddress:
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "extended-address");
                            break;
                        case AddressElement.Region:
                            if (this.StateCode)
                            {
                                tag = HtmlTextWriterTag.Unknown;
                                writer.AddAttribute(HtmlTextWriterAttribute.Title, addressProperty.Value);

                                KeyValuePair<string, string> keyValuePair = Utility.GetStates().Where(q => q.Value.ToLower(CultureInfo.InvariantCulture) == addressProperty.Value.ToLower(CultureInfo.InvariantCulture)).FirstOrDefault();

                                value = keyValuePair.Key.ToUpper(CultureInfo.InvariantCulture);
                            }

                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "region");
                            break;
                        case AddressElement.Locality:
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "locality");
                            break;
                        case AddressElement.PostalCode:
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "postal-code");
                            break;
                        case AddressElement.CountryName:
                            if (this.CountryCode)
                            {
                                tag = HtmlTextWriterTag.Unknown;
                                writer.AddAttribute(HtmlTextWriterAttribute.Title, addressProperty.Value);

                                KeyValuePair<string, string> keyValuePair = Utility.GetCountries().Where(q => q.Value.ToLower(CultureInfo.InvariantCulture) == addressProperty.Value.ToLower(CultureInfo.InvariantCulture)).FirstOrDefault();

                                value = keyValuePair.Key.ToUpper(CultureInfo.InvariantCulture);
                            }
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "country-name");
                            break;
                        default:
                            break;
                    }

                    writer.Indent++;
                    writer.RenderBeginTag(tag == HtmlTextWriterTag.Unknown ? "abbr" : tag.ToString().ToLower());

                    writer.Write(value);

                    writer.RenderEndTag();
                    writer.Indent--;
                }

                if (addressContainer.HtmlTag != HtmlTextWriterTag.Unknown)
                {
                    writer.RenderEndTag();
                }
            }

            writer.RenderEndTag();
            writer.WriteLine();
        }
    }
}
